<template>
  <div class="match-logs-container">
    <div class="header">
      <h2>比赛提交记录</h2>
      <div class="controls">
        <el-button @click="refreshData" :loading="loading"> 刷新 </el-button>
      </div>
    </div>

    <el-table
      :data="filteredData"
      v-loading="loading"
      stripe
      border
      style="width: 100%"
      :default-sort="{ prop: 'timestamp', order: 'descending' }"
    >
      <el-table-column prop="userId" label="用户" width="120" sortable />
      <el-table-column prop="timestamp" label="提交时间" width="200" sortable>
        <template #default="scope">
          {{ formatTimestamp(scope.row.timestamp) }}
        </template>
      </el-table-column>
      <el-table-column label="操作" width="300" fixed="right">
        <template #default="scope">
          <el-button
            type="primary"
            size="small"
            @click="viewDetail(scope.row)"
            :loading="scope.row.detailLoading"
          >
            查看详情
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <div class="pagination">
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="[10, 20, 50, 100]"
        :total="totalCount"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <!-- 查看代码对话框 - 已移除，代码现在在详情对话框中显示 -->

    <!-- 详情对话框 -->
    <el-dialog
      v-model="detailDialogVisible"
      width="80%"
      v-loading="detailLoading"
    >
      <div v-if="currentDetail.jsonData && currentDetail.jsonData.length > 0">
        <!-- 如果有多个提交记录，显示标签页 -->
        <el-tabs v-model="activeSubmissionTab" type="card">
          <el-tab-pane
            v-for="(submission, index) in currentDetail.jsonData"
            :key="index"
            :label="`提交 ${index + 1} ${submission.resultdata}`"
            :name="index.toString()"
          >
            <div class="submission-detail">
              <el-descriptions :column="2" border>
                <el-descriptions-item label="用户ID">{{
                  submission.userid
                }}</el-descriptions-item>
                <el-descriptions-item label="题目ID">{{
                  submission.questionid
                }}</el-descriptions-item>
                <el-descriptions-item label="题目标题">{{
                  submission.question?.name || submission.matchquestion?.name
                }}</el-descriptions-item>
                <el-descriptions-item label="提交时间">{{
                  dayjs(submission.createdAt).format("YYYY-MM-DD HH:mm:ss")
                }}</el-descriptions-item>
                <el-descriptions-item label="得分">{{
                  submission.df
                }}</el-descriptions-item>
                <el-descriptions-item label="编程语言">{{
                  submission.language
                }}</el-descriptions-item>
                <el-descriptions-item label="结果">{{
                  submission.resultdata
                }}</el-descriptions-item>
                <el-descriptions-item label="详细结果" :span="2">{{
                  submission.resultdataarr?.join(",")
                }}</el-descriptions-item>
              </el-descriptions>

              <el-divider content-position="left">提交代码</el-divider>
              <pre class="code-content">{{
                submission.context || "无代码内容"
              }}</pre>

              <!-- 如果有详细评测信息 -->
              <div
                v-if="submission.info && Array.isArray(submission.info)"
                class="test-cases"
              >
                <el-divider content-position="left">测试点详情</el-divider>
                <el-table :data="submission.info" border size="small">
                  <el-table-column prop="result" label="结果" width="100">
                    <template #default="scope">
                      <el-tag>
                        {{ scope.row.tn[0] }}
                      </el-tag>
                    </template>
                  </el-table-column>
                  <el-table-column prop="t" label="耗时" width="100">
                    <template #default="scope">
                      {{ time([scope.row]) }}
                    </template>
                  </el-table-column>
                  <el-table-column prop="memory" label="内存" width="100">
                    <template #default="scope">
                      {{ memory(scope.row) }}
                    </template>
                  </el-table-column>
                  <el-table-column prop="score" label="得分" width="80" />
                </el-table>
              </div>
            </div>
          </el-tab-pane>
        </el-tabs>
      </div>
      <el-empty v-else description="正在加载详情数据..." />
      <template #footer>
        <el-button @click="detailDialogVisible = false">关闭</el-button>
        <el-button
          v-if="currentDetail.jsonData && currentDetail.jsonData.length > 0"
          type="primary"
          @click="copyCode"
        >
          复制当前代码
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from "vue";
import { dayjs, ElMessage, ElMessageBox } from "element-plus";
import OSS from "ali-oss";
import Studycodemodel from "@/mysql_interface/studycodemodel";
import { ossupload } from "@/api";
import { memory, time } from "../../../util/code";
const p = defineProps<{ matchId: number; data: Studycodemodel.Iactivity }>();

// 响应式数据
const loading = ref(false);
const detailLoading = ref(false);
const tableData = ref<MatchLogItem[]>([]);
const searchKeyword = ref("");
const currentPage = ref(1);
const pageSize = ref(20);
const totalCount = ref(0);
const detailDialogVisible = ref(false);
const currentDetail = ref<MatchLogItem>({} as MatchLogItem);
const activeSubmissionTab = ref("0");

// OSS配置
const ossConfig = ref<OSSConfig | null>(null);

interface OSSConfig {
  accessKeyId: string;
  accessKeySecret: string;
  securityToken: string;
  expiration: string;
}

interface MatchLogItem {
  userId: string;
  timestamp: number;
  timestampStr: string;
  ossPath: string;
  jsonData?: Studycodemodel.Imatchuserquestion[];
  detailLoading?: boolean;
  downloadLoading?: boolean;
}

// 计算属性
const filteredData = computed(() => {
  if (!searchKeyword.value) {
    return tableData.value.slice(
      (currentPage.value - 1) * pageSize.value,
      currentPage.value * pageSize.value
    );
  }

  const filtered = tableData.value.filter(
    (item) =>
      item.userId.toString().includes(searchKeyword.value) ||
      item.ossPath.toLowerCase().includes(searchKeyword.value.toLowerCase())
  );

  totalCount.value = filtered.length;
  return filtered.slice(
    (currentPage.value - 1) * pageSize.value,
    currentPage.value * pageSize.value
  );
});

// 方法
const getOSSCredentials = async () => {
  try {
    const response = await ossupload();
    ossConfig.value = response;
    return response;
  } catch (error) {
    ElMessage.error("获取OSS临时权限失败");
    throw error;
  }
};

const fetchMatchLogs = async () => {
  if (!p.matchId) {
    ElMessage.warning("请提供有效的比赛ID");
    return;
  }

  loading.value = true;
  try {
    // 获取OSS临时权限
    const credentials = await getOSSCredentials();

    // 构建OSS客户端
    const client = new OSS({
      region: "oss-cn-qingdao",
      accessKeyId: credentials.accessKeyId,
      accessKeySecret: credentials.accessKeySecret,
      stsToken: credentials.securityToken,
      bucket: "hterobot-tmp",
    });

    // 获取比赛文件夹下的所有文件
    const matchPrefix = `match/${p.matchId}/`;
    const result = await client.list(
      {
        prefix: matchPrefix,
        "max-keys": 1000,
      },
      {}
    );

    const logItems: MatchLogItem[] = [];

    if (result.objects) {
      for (const obj of result.objects) {
        if (obj.name.endsWith(".json")) {
          try {
            // 解析文件路径: match/比赛id/用户id/提交时间戳.json
            const pathParts = obj.name.split("/");
            if (pathParts.length === 4) {
              const userId = pathParts[2];
              const timestampStr = pathParts[3].replace(".json", "");
              const timestamp = parseInt(timestampStr);

              const logItem: MatchLogItem = {
                userId: userId,
                timestamp: timestamp,
                timestampStr: timestampStr,
                ossPath: obj.name,
                detailLoading: false,
                downloadLoading: false,
              };

              logItems.push(logItem);
            }
          } catch (parseError) {
            console.warn("解析文件路径失败:", obj.name, parseError);
          }
        }
      }
    }

    // 按时间戳降序排序
    logItems.sort((a, b) => b.timestamp - a.timestamp);

    tableData.value = logItems;
    totalCount.value = logItems.length;
  } catch (error) {
    console.error("获取比赛日志失败:", error);
    ElMessage.error("获取比赛日志失败: " + (error as Error).message);
  } finally {
    loading.value = false;
  }
};

const refreshData = () => {
  currentPage.value = 1;
  fetchMatchLogs();
};

const formatTimestamp = (timestamp: number) => {
  if (!timestamp) return "未知时间";
  return new Date(timestamp * 1000).toLocaleString("zh-CN");
};

const viewCode = (row: MatchLogItem) => {
  // 现在直接查看详情，代码在详情对话框中显示
  viewDetail(row);
};

const viewDetail = async (row: MatchLogItem) => {
  if (row.jsonData) {
    // 如果已经加载过数据，直接显示
    currentDetail.value = row;
    detailDialogVisible.value = true;
    return;
  }

  // 设置加载状态
  row.detailLoading = true;
  detailLoading.value = true;

  try {
    // 获取OSS临时权限
    const credentials = await getOSSCredentials();

    // 构建OSS客户端
    const client = new OSS({
      region: "oss-cn-qingdao",
      accessKeyId: credentials.accessKeyId,
      accessKeySecret: credentials.accessKeySecret,
      stsToken: credentials.securityToken,
      bucket: "hterobot-tmp",
    });

    // 下载并解析JSON文件
    const objectResult = await client.get(row.ossPath);
    const jsonData = JSON.parse(objectResult.content.toString());

    // 将数据保存到row中，避免重复下载
    row.jsonData = jsonData;

    currentDetail.value = row;
    detailDialogVisible.value = true;
  } catch (error) {
    console.error("获取详情失败:", error);
    ElMessage.error("获取详情失败: " + (error as Error).message);
  } finally {
    row.detailLoading = false;
    detailLoading.value = false;
  }
};

const downloadJson = async (row: MatchLogItem) => {
  row.downloadLoading = true;

  try {
    let jsonData = row.jsonData;

    if (!jsonData) {
      // 如果还没有加载过数据，先下载
      const credentials = await getOSSCredentials();
      const client = new OSS({
        region: "oss-cn-qingdao",
        accessKeyId: credentials.accessKeyId,
        accessKeySecret: credentials.accessKeySecret,
        stsToken: credentials.securityToken,
        bucket: "hterobot-tmp",
      });

      const objectResult = await client.get(row.ossPath);
      jsonData = JSON.parse(objectResult.content.toString());
      row.jsonData = jsonData; // 缓存数据
    }

    const jsonStr = JSON.stringify(jsonData, null, 2);
    const blob = new Blob([jsonStr], { type: "application/json" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = `${row.userId}_${row.timestampStr}.json`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
    ElMessage.success("JSON文件下载成功");
  } catch (error) {
    console.error("下载失败:", error);
    ElMessage.error("下载失败: " + (error as Error).message);
  } finally {
    row.downloadLoading = false;
  }
};

const copyCode = async () => {
  try {
    if (
      !currentDetail.value.jsonData ||
      currentDetail.value.jsonData.length === 0
    ) {
      ElMessage.warning("没有可复制的代码内容");
      return;
    }

    let codeContent = "";

    if (currentDetail.value.jsonData.length === 1) {
      // 只有一个提交记录
      codeContent = currentDetail.value.jsonData[0].context || "";
    } else {
      // 多个提交记录，复制当前选中标签页的代码
      const activeIndex = parseInt(activeSubmissionTab.value);
      codeContent = currentDetail.value.jsonData[activeIndex]?.context || "";
    }

    if (!codeContent) {
      ElMessage.warning("当前提交没有代码内容");
      return;
    }

    await navigator.clipboard.writeText(codeContent);
    ElMessage.success("代码已复制到剪贴板");
  } catch (error) {
    ElMessage.error("复制失败");
  }
};

const handleSizeChange = (newSize: number) => {
  pageSize.value = newSize;
  currentPage.value = 1;
};

const handleCurrentChange = (newPage: number) => {
  currentPage.value = newPage;
};

// 监听比赛ID变化
watch(
  () => p.matchId,
  (newMatchId) => {
    if (newMatchId) {
      fetchMatchLogs();
    }
  },
  { immediate: true }
);

onMounted(() => {
  if (p.matchId) {
    fetchMatchLogs();
  }
});
</script>

<style scoped>
.match-logs-container {
  padding: 20px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 16px;
  border-bottom: 1px solid #ebeef5;
}

.header h2 {
  margin: 0;
  color: #303133;
  font-size: 18px;
  font-weight: 600;
}

.controls {
  display: flex;
  align-items: center;
  gap: 10px;
}

.pagination {
  margin-top: 20px;
  display: flex;
  justify-content: center;
}

.code-content {
  background: #f5f7fa;
  padding: 16px;
  border-radius: 6px;
  font-family: "Courier New", monospace;
  font-size: 14px;
  line-height: 1.5;
  max-height: 400px;
  overflow-y: auto;
  border: 1px solid #dcdfe6;
  white-space: pre-wrap;
  word-wrap: break-word;
}

.el-table {
  font-size: 14px;
}

.el-table .el-table__cell {
  padding: 8px 0;
}

.el-button--text {
  padding: 0;
  margin-right: 8px;
}

.el-button--text:last-child {
  margin-right: 0;
}

:deep(.el-table__header) {
  background-color: #fafafa;
}

:deep(.el-table__header th) {
  background-color: #fafafa !important;
  color: #606266;
  font-weight: 600;
}

:deep(.el-table__row:hover) {
  background-color: #f5f7fa;
}

:deep(.el-tag) {
  font-weight: 500;
}

.el-descriptions {
  margin-top: 20px;
}

:deep(.el-descriptions__label) {
  font-weight: 600;
  color: #606266;
}

:deep(.el-descriptions__content) {
  color: #303133;
}

.el-loading-mask {
  background-color: rgba(255, 255, 255, 0.9);
}

.submission-detail {
  margin-top: 20px;
}

.test-cases {
  margin-top: 20px;
}

.test-cases .el-table {
  margin-top: 10px;
}

.el-tabs .el-tab-pane {
  max-height: 600px;
  overflow-y: auto;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .header {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
  }

  .controls {
    width: 100%;
    flex-wrap: wrap;
  }

  .el-input {
    width: 100% !important;
    margin-right: 0 !important;
    margin-bottom: 10px;
  }
}
</style>
